﻿using DingTalk.Core;
using DingTalk.Core.Models;
using DingTalk.Corp.Configurations;
using DingTalk.Corp.Log;
using MiniFox.Components;
using MiniFox.Configurations;
using MiniFox.Log;
using MiniFox.Web;
using System.Xml.Linq;

namespace DingTalk.Corp
{
    /// <summary>
    /// 
    /// </summary>
    public class DingTalkAgentService : DingTalkServiceBase, IDingTalkAgentService
    {
        private string _name;
        private DingTalkCorpServiceConfiguration _serverConfig;
        private IDingTalkCorpConfiguration _secureConfig;
        private IDingTalkAgent _setting;

        /// <summary>
        /// 
        /// </summary>
        public DingTalkAgentService() : this(string.Empty)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        public DingTalkAgentService(string name)
        {
            this._name = name;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="setting"></param>
        public DingTalkAgentService(IDingTalkAgent setting)
        {
            this._name = setting.Name;
            this._setting = setting;
        }

        /// <summary>
        /// 
        /// </summary>
        [AutoWired]
        public DingTalkCorpConfigProvider ConfigProvider
        {
            get;
            set;
        }

        private IDingTalkCorpConfiguration SecureConfiguration
        {
            get
            {
                if (this._secureConfig == null)
                {
                    _secureConfig = this.ConfigProvider.GetSecureConfig();
                }
                return _secureConfig;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        protected virtual DingTalkCorpServiceConfiguration ServerConfig
        {
            get
            {
                if (this._serverConfig == null)
                    _serverConfig = ConfigurationFactory.GetConfig<DingTalkCorpServiceConfiguration>();
                return _serverConfig;
            }
        }
        #region 
        /// <summary>
        /// 
        /// </summary>
        public override string Name
        {
            get
            {
                return this._name;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string AppKey
        {
            get
            {
                return this.Setting.AppKey;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string AppSecret
        {
            get
            {
                return this.Setting.AppSecret;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public long AgentID
        {
            get
            {
                return Convert.ToInt64(this.Setting.AgentID);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string CorpID
        {
            get
            {
                return SecureConfiguration.CorpID;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override Uri AccessTokenUri
        {
            get
            {
                return new Uri(ServerConfig.AccessTokenUri);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public IDingTalkAgent Setting
        {
            get
            {
                if (this._setting == null)
                {
                    this._setting = ConfigProvider.GetAgentSetting(this.Name);
                }
                return this._setting;
            }
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="method"></param>
        /// <param name="requestData"></param>
        /// <param name="responseData"></param>
        /// <param name="elapsed"></param>
        protected override void WriteLog(string uri, string method, string requestData, string responseData, int elapsed)
        {
            if (string.IsNullOrEmpty(this.ServerConfig.LoggerName))
                return;
            var factory = ComponentFactory.GetComponent<LoggerFactory>();
            ILogger logger = factory.CreateLogger(this.ServerConfig.LoggerName);

            logger.WriteInfo(new DingTalkCorpServiceLogContent
            {
                CorpID = this.CorpID,
                AgentID = this.Setting.AgentID,
                AppKey = this.AppKey,
                AppSecret = this.AppSecret,
                HttpMethod = method,
                RequestUri = uri,
                Elapsed = elapsed,
                RequestData = requestData,
                ResponseData = responseData
            });
        }

        #region access token

        /// <summary>
        /// 获取令牌（新版）
        /// </summary>
        /// <returns></returns>
        protected override async Task<AccessToken> GetAccessTokenAsync()
        {
            var uri = this.AccessTokenUri;
            var accessTokenRequest = new AccessTokenRequest 
            { 
                AppKey = this.AppKey, 
                AppSecret = this.AppSecret
            };

            AccessTokenResponse response = await uri.HttpPostJsonAsync<AccessTokenRequest, AccessTokenResponse>(accessTokenRequest);

            return new AccessToken
            {
                Token = response.AccessToken,
                ExpiresIn = response.ExpiresIn
            };
        }

        #endregion

    }
}

